#include "../logs/clog.hpp"
#include <vector>
#include <thread>
#include <chrono>

void bench(const std::string &logger_name,size_t thr_count,size_t msg_count,size_t msg_len)
{
    // 获取指定名称的日志器
    clog::Logger::ptr logger = clog::GetLogger(logger_name);
    if (logger.get() == nullptr)
    {
        return;
    }
    std::cout << "测试日志 :  " << msg_count << "条, 总大小 : " << msg_count * msg_len / 1024 << "KB\n";
    // 组织指定长度的日志消息
    std::string msg(msg_len - 1, 'A'); // 留一个位置方便换行显示
    // 创建指定数量的线程
    std::vector<std::thread> threads;
    // 记录每个线程所花费的时间
    std::vector<double> cost_arry(thr_count);
    // 每个线程打印的日志条数
    size_t msg_per_thr = msg_count / thr_count;
    for (int i = 0; i < thr_count; i++)
    {
        //i传值传参保证每个线程各有一份i
        threads.emplace_back([&,i](){
            //线程函数内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            //开始循环写日志
            for(int j = 0; j < msg_per_thr; j++)
            {
                logger->fatal("%s",msg.c_str());
            }
            //线程函数内部结束计时
            auto end = std::chrono::high_resolution_clock::now();
            auto cost = std::chrono::duration_cast<std::chrono::duration<double>>(end - start);
            //记录每个线程执行时间
            cost_arry[i]=cost.count();
            std::cout << "\t线程" << i << " : " << "\t输出数量 : " << msg_per_thr << ", 耗时 : " <<cost.count() << "s" << std::endl;
        });
    }
    // 回收线程
    for (int i = 0; i < thr_count; i++)
    {
        threads[i].join();
    }
    // 计算总耗时：因为在多线程中，是并发执行的，因此总耗时就是耗费最高的时间的那个线程所消耗的时间
    double max_cost = cost_arry[0];
    for (int i = 0; i < thr_count; i++)
    {
        max_cost = max_cost < cost_arry[i] ? cost_arry[i] : max_cost;
    }
    // 每秒输出的条数
    size_t msg_per_sec = msg_count / max_cost;
    // 每秒输出的大小
    size_t size_per_sec = msg_count * msg_len / (max_cost * 1024);
    // 输出结果
    std::cout << "\t总耗时 : " << max_cost << "s\n";
    std::cout << "\t每秒输出日志数量 : " << msg_per_sec << "条\n";
    std::cout << "\t每秒输出日志大小 : " << size_per_sec << "KB\n";
}

void bench_sync()
{
    const char *logger_name = "sync_logger";
    // std::unique_ptr<clog::LoggerBuilder> bd(new clog::GlobalLoggerBuilder());
    // bd->buildloggername(logger_name);
    // bd->buildformatter("[%m]%n");
    // bd->buildloggertype(clog::LoggerType::LOG_SYNC);
    // bd->buildsink<clog::FileSink>("./logfile/sync.log");
    // bd->build();

    // bench(logger_name,1,1000000,100);
    // //bench(logger_name,3,1000000,100);

    clog::GlobalLoggerBuilder::ptr lbp(new clog::GlobalLoggerBuilder);
    lbp->buildloggername(logger_name);
    lbp->buildformatter("%m%n");
    lbp->buildsink<clog::FileSink>("./logs/sync.log");
    lbp->buildloggertype(clog::LoggerType::LOG_SYNC);
    lbp->build();
    //bench(logger_name, 1, 1000000, 100);
    bench(logger_name, 5, 1000000, 100);

}



void bench_async()
{
    const char *logger_name = "async_logger";
    std::unique_ptr<clog::LoggerBuilder> bd(new clog::GlobalLoggerBuilder());
    bd->buildloggername(logger_name);
    bd->buildformatter("%m%n");
    bd->buildEnableUnsaveAsync();  //启动非安全模式，忽略实际落地的时间
    bd->buildloggertype(clog::LoggerType::LOG_ASYNC);
    bd->buildsink<clog::FileSink>("./logfile/async.log");
    bd->build();

    bench(logger_name,1,1000000,100);
    //bench(logger_name,5,1000000,100);

}

int main()
{
    bench_sync();
    //bench_async();
    return 0;
}